﻿package com.PlantVsZombies.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JPanel;

import com.PlantVsZombies.Bullet.Bomb;
import com.PlantVsZombies.Bullet.Bullet;
import com.PlantVsZombies.Plants.FightPlant;
import com.PlantVsZombies.Zombies.RandomZombie;
import com.PlantVsZombies.Zombies.Star;
import com.PlantVsZombies.Zombies.Zombie_Enemy;
import com.PlantVsZombies.common.Zombie;
import com.PlantVsZombies.constant.Constant;
import com.PlantVsZombies.game.MainFrame;
import com.PlantVsZombies.game.Menu;
import com.PlantVsZombies.util.ImageUtil;
import com.PlantVsZombies.util.MP3Player;
import com.PlantVsZombies.util.MusicPlay;
import com.PlantVsZombies.util.MusicUtil;

public class GamePanel2 extends JPanel implements Runnable, Constant {

	// 玩家植物
	FightPlant player;
	// 僵尸集合
	ArrayList<Zombie_Enemy> zombie = new ArrayList<Zombie_Enemy>();
	// 爆炸集合
	ArrayList<Bomb> bomb = new ArrayList<Bomb>();
	// 星星集合
	public static ArrayList<Star> star = new ArrayList<Star>();
	// 背景音乐
	MP3Player backmusic;
	// 随机数，用于产生星星
	Random rd = new Random();

	public static int score = 0;
	private int rank = 1;

	int shootZombie;
	int x;
	int wudi = 0;

	String gamestate;
	boolean isGameOver = false;
	boolean isPass = false;
	Thread t;

	public GamePanel2() {
		
	}

	public void startAction(int rank, int score) {
		// TODO Auto-generated method stub
		shootZombie= 0;
		player = new FightPlant(50, 300);
		gamestate = "start";
		isGameOver = false;
		backmusic = new MP3Player(MusicUtil.backmusic4);
		if (!t.isAlive())
			t.start();
		if (!backmusic.isAlive())
			backmusic.start();
		
		this.score = score;
		this.rank = rank;
	}

	// 游戏结束
	public void gameOver() {
		gamestate = "gameover";
		score = 0;
		rank = 1;
		backmusic.Stop();
		for (int i = 0; i < zombie.size(); i++) {
			zombie.get(i).setSuspend(true);
			for (Bullet bt : zombie.get(i).getBullet()) {
				bt.setSuspend(true);
			}
		}
		for (int i = 0; i < player.getBullet().size(); i++) {
			player.getBullet().get(i).setSuspend(true);
		}
		for (int i = 0; i < star.size(); i++) {
			star.get(i).setSuspend(true);
		}
		for (int i = 0; i < bomb.size(); i++) {
			bomb.get(i).setSuspend(true);
		}
		zombie.removeAll(zombie);
		star.removeAll(star);
		bomb.removeAll(bomb);
	}

	// 暂停游戏
	public void pauseGame() {
		gamestate = "pause";
		backmusic.Stop();
		for (int i = 0; i < zombie.size(); i++) {
			zombie.get(i).setSuspend(true);
			for (Bullet bt : zombie.get(i).getBullet()) {
				bt.setSuspend(true);
			}
		}
		for (int i = 0; i < player.getBullet().size(); i++) {
			player.getBullet().get(i).setSuspend(true);
		}
		for (int i = 0; i < star.size(); i++) {
			star.get(i).setSuspend(true);
		}
		for (int i = 0; i < bomb.size(); i++) {
			bomb.get(i).setSuspend(true);
		}
	}

	// 继续游戏
	public void continueGame() {
		gamestate = "start";
		for (int i = 0; i < zombie.size(); i++) {
			for (Bullet bt : zombie.get(i).getBullet()) {
				bt.setSuspend(false);
			}
			zombie.get(i).setSuspend(false);
		}
		for (int i = 0; i < player.getBullet().size(); i++) {
			player.getBullet().get(i).setSuspend(false);
		}
		for (int i = 0; i < star.size(); i++) {
			star.get(i).setSuspend(false);
		}
		for (int i = 0; i < bomb.size(); i++) {
			bomb.get(i).setSuspend(false);
		}
	}

	// 过关
	public void passGame() {
		gamestate = "pass";
		rank++;
		backmusic.Stop();
		for (int i = 0; i < zombie.size(); i++) {
			zombie.get(i).setSuspend(true);
			for (Bullet bt : zombie.get(i).getBullet()) {
				bt.setSuspend(true);
			}
		}
		for (int i = 0; i < player.getBullet().size(); i++) {
			player.getBullet().get(i).setSuspend(true);
		}
		for (int i = 0; i < star.size(); i++) {
			star.get(i).setSuspend(true);
		}
		for (int i = 0; i < bomb.size(); i++) {
			bomb.get(i).setSuspend(true);
		}
		zombie.removeAll(zombie);
		star.removeAll(star);
		bomb.removeAll(bomb);
	}

	/*
	 * 
	 * (线程，实现面板的刷新
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			if(isGameOver){
				return;
			}
			if (gamestate.equals("start")) {
				if (shootZombie++ % 400 == 0) {
					// Zombie zb = RandomZombie.randomZombie();
					Zombie_Enemy zb = new Zombie_Enemy(800, rd.nextInt(500),
							rd.nextInt(15) + 1);
					zb.start();
					zombie.add(zb);
				}
				if(shootZombie == 3000){
					Zombie_Enemy boss = new Zombie_Enemy(700, 200, 10,
							ImageUtil.boss[rank - 1], (rank - 1) * 800 + 800);
					boss.start();
					zombie.add(boss);
				}
				if (player.getLife() < 0) {
					player.setLive(false);
					backmusic.setAlive(false);
				}
				zombieisAttacked(zombie);
				playerisAttacked(zombie);
				playerAttackZombie(zombie);
				isGameOver();
				isPass();
				eatStar();

				if (player.isWudi()) {
					if (wudi++ > 2000) {
						player.setWudi(false);
						wudi = 0;
					}

				}
				try {

					Thread.sleep(3);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (!gamestate.equals("gameover") && !gamestate.equals("pass"))
				repaint();
		}
	}

	/*
	 * 游戏总开关 添加鼠标监听和键盘监听
	 */
	public void Action() {
		gamestate = "";
		t = new Thread(this);
		
		
		addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				switch (e.getKeyCode()) {
				case KeyEvent.VK_J:
					player.shootBullet();
					break;
				case KeyEvent.VK_SPACE:
					player.shootBigBullet();
					break;
				case KeyEvent.VK_P:
					pauseGame();
					break;
				case KeyEvent.VK_ENTER:
					if (gamestate.equals("") || gamestate.equals("gameover")
							|| gamestate.equals("pass")){
						//t = new Thread(new GamePanel2());
						Action();
						startAction(rank, score);
					}
					else if (gamestate.equals("pause"))
						continueGame();
					break;
				case KeyEvent.VK_ESCAPE:
					if (gamestate.equals("gameover")) {
						isGameOver = true;
						MainFrame.P.remove(MainFrame.p2);
						//MainFrame.p2 = null;
						MainFrame.P.add(MainFrame.m);
						MainFrame.P.repaint();
						Menu.menu.loop();
						MainFrame.P.setVisible(true);
					}
					break;
				}
				repaint();
			}

		});
		addMouseListener(new MouseListener() {
			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				if (gamestate.equals("start"))
					player.shootBullet();
			}

			public void mouseReleased(MouseEvent e) {
			}

			public void mouseExited(MouseEvent e) {
			}

			public void mouseEntered(MouseEvent e) {
			}

			public void mouseClicked(MouseEvent e) {
			}
		});
		addMouseMotionListener(new MouseMotionListener() {

			@Override
			public void mouseMoved(MouseEvent e) {
				// TODO Auto-generated method stub
				if (gamestate == "start") {
					player.setX(e.getX());
					player.setY(e.getY());
				}
			}

			@Override
			public void mouseDragged(MouseEvent e) {
				// TODO Auto-generated method stub

			}
		});
	}

	// 画图
	public void paint(Graphics g) {
		super.paint(g);
		if (gamestate.equals("start") || gamestate.equals("pause")) {
			paintBack(g);
			drawScore(g);
			drawRank(g);
			player.drawMe(g, player.getX(), player.getY());
			drawZombie(g);
			drawBomb(g);

			drawStar(g);
		} else if (gamestate.equals("gameover")) {
			g.drawImage(ImageUtil.pattern2gameover.getImage(), 0, 0, this);
		} else if (gamestate.equals("pass")) {
			g.drawImage(ImageUtil.pattern2pass.getImage(), 0, 0, this);
		}

		else {

			g.drawImage(ImageUtil.pattern2back1.getImage(), 0, 0, this);
		}
	}

	// 画背景
	public void paintBack(Graphics g) {

		g.drawImage(ImageUtil.BACKGROUND3, -600, 0, 1300, 600, 0, 0, 1500, 600,
				this);
	}

	// 画爆炸特效
	public void drawBomb(Graphics g) {
		for (int i = 0; i < bomb.size(); i++) {
			if (bomb.get(i).getLive())
				bomb.get(i).drawMe(g);
			else {
				bomb.remove(i);
			}
		}
	}

	// 画僵尸
	public void drawZombie(Graphics g) {
		for (int i =0 ; i<zombie.size(); i++) {
			if (zombie.get(i).getLive())
				zombie.get(i).drawMe(g);
			else
				zombie.remove(i);
		}
	}

	// 画分数
	public void drawScore(Graphics g) {
		g.setColor(Color.GREEN);
		g.setFont(new Font("叶根友毛笔行书2.0版", Font.PLAIN, 40));
		g.drawString("分数:" + score, 600, 50);
	}

	// 画管卡
	public void drawRank(Graphics g) {
		g.setColor(Color.GREEN);
		g.setFont(new Font("叶根友毛笔行书2.0版", Font.PLAIN, 40));
		g.drawString("第" + rank + "关", 400, 100);
	}

	// 画星星
	public void drawStar(Graphics g) {
		for (int i = 0; i < star.size(); i++) {
			Star s = star.get(i);
			if (s.isLive) {
				s.drawMe(g);
			} else
				star.remove(s);
		}
	}

	// 判断游戏是否结束
	public void isGameOver() {

		if (player.getLife() <= 0) {
			isGameOver = true;
			gameOver();
		}
	}

	public void isPass() {
		for (int i = 0; i < zombie.size(); i++)
			if ((zombie.get(i).getType() == -1) && zombie.get(i).getLife() <= 2) {
				isPass = true;
				passGame();
			}
	}

	// 吃星星
	public void eatStar() {
		for (int i = 0; i < star.size(); i++) {
			Star s = star.get(i);
			if (checkImpact(player.getX(), player.getY(), 60, 80, s.getX(),
					s.getY(), 30, 30)) {

				if (s.getType() == 0) {
					player.setEnergy(player.getEnergy() + 1);
					if (player.getEnergy() % 10 == 0) {
						player.setEnergy(0);
						player.setBigbullet(player.getBigbullet() + 1);
					}
				}

				else if (s.getType() == 1) {
					if (player.getFire() < 3){
						player.setFire(player.getFire() + 1);
					}
					player.setLife(10);
					
				} else {
					player.setWudi(true);
				}
				s.setLive(false);
			}
		}
	}

	// 检测两个物体是否碰撞
	public boolean checkImpact(int x1, int y1, int w1, int h1, int x2, int y2,
			int w2, int h2) {
		if (x1 + w1 >= x2 && y1 + h1 >= y2 && x2 + w2 >= x1 && y2 + h2 >= y1) {
			return true;
		}
		return false;
	}

	// 添加爆炸效果
	public void addBomb(int x, int y) {
		Bomb bm = new Bomb(x, y, ImageUtil.bomb2.getImage());// 添加爆炸
		bm.start();
		bomb.add(bm);
	}

	public void zombieisAttacked(ArrayList<Zombie_Enemy> zombie) {
		for (int i = 0; i < player.getBullet().size(); i++) {
			// 获取玩家子弹
			Bullet b = player.getBullet().get(i);
			for (Zombie_Enemy zb : zombie) {
				if (checkImpact(b.getX(), b.getY(), 20, 20, zb.getX(),
						zb.getY(), zb.getImage().getIconWidth(), zb.getImage()
								.getIconHeight())) {
					/*
					 * 若击中 子弹死亡 僵尸生命减少 添加爆炸
					 */
					b.setLive(false);// 子弹死亡
					zb.setLife(zb.getLife() - player.getFire()); // 僵尸生命减一

					// if (zb.getLife() == 1)
					// produceStar(zb.getX(), zb.getY());
					addBomb(zb.getX(), zb.getY());

					return;
				}
			}
		}
	}

	public void playerAttackZombie(ArrayList<Zombie_Enemy> zombie) {
		for (int i = 0; i < zombie.size(); i++) {
			Zombie_Enemy zb = zombie.get(i);
			if (checkImpact(player.getX(), player.getY(), 60, 100, zb.getX(),
					zb.getY(), zb.getImage().getIconWidth(), zb.getImage()
							.getIconHeight())) {
				if (!player.isWudi())
					player.setLife(player.getLife() - 1);
				if (!zb.isIsboss())
					zb.setLive(false);
				addBomb(zb.getX(), zb.getY());
			}
		}
	}

	public void playerisAttacked(ArrayList<Zombie_Enemy> zombie) {
		for (int i = 0; i < zombie.size(); i++) {
			Zombie_Enemy zb = zombie.get(i);
			for (int j = 0; j < zb.getBullet().size(); j++) {
				Bullet bt = zb.getBullet().get(j);
				if (bt.getX() > player.getX() && bt.getX() < player.getX() + 50
						&& bt.getY() > player.getY()
						&& bt.getY() < player.getY() + 50) {

					/*
					 * 若击中 子弹死亡 僵尸生命减少 添加爆炸
					 */

					bt.setLive(false);// 子弹死亡
					if (!player.isWudi())
						player.setLife(player.getLife() - 1); // 生命减一

					addBomb(player.getX(), player.getY());
					return;
				}
			}
		}

	}

}
